﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ShprossesBuilder.Calculations;
using ITAP.Core.Modelling;
using ITAP.Core.Calculations;

namespace ITAP.ShprossesBuilder.Modelling.Components.Constraints
{
    [Serializable]
    public class InnerStubStickConnectorAngleIntervalConstraint : IConstraint
    {
        private AngleInterval allowedAngleInterval;

        public InnerStubStickConnectorAngleIntervalConstraint(AngleInterval interval)
        {
            this.allowedAngleInterval = interval.Clone() as AngleInterval;                
        }

        #region IConstraint Members

        public bool Check(IComponent component)
        {
            return false;
        }

        public void Fix(IComponent component)
        {
            if (!enabled)
                return;
            if (!(component is ShprossConnector))
                return;
            StickConnector connector = component as StickConnector;
            foreach (IComponent connectedComponent in component.ConnectedComponents)
            {                
                if (connectedComponent is ShprossConnectorStub)
                {
                    ModelVector stickTangent = connectedComponent.Primitives[0].GetTangent(0);
                    ModelVector stubTangent = connectedComponent.Primitives[0].GetTangent(0);

                    Angle angle = ModelCalculations.GetAngleBetweenVectors(stubTangent, stickTangent, false);
                    if (!allowedAngleInterval.IsAngleInInterval(angle))
                    {
                        Angle angleToRotate = allowedAngleInterval.MiddleAngle - angle;
                        if (connectedComponent.Parent is ShprossConnector)
                            connectedComponent.Parent.Rotate(angle.Value);
                    }
                    return;
                }
            }

        }

        private bool enabled = true;
        public bool Enabled
        {
            get
            {
                return enabled;
            }
            set
            {
                enabled = value;
            }
        }

        public ConstraintAction Action
        {
            get { return ConstraintAction.Fix; }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            InnerStubStickConnectorAngleIntervalConstraint clone = new InnerStubStickConnectorAngleIntervalConstraint(allowedAngleInterval);
            clone.Enabled = this.enabled;
            return clone;
        }

        #endregion
    }
}
